package com.gaofans.nrpc.common.context;

import io.netty.util.NettyRuntime;
import io.netty.util.concurrent.*;
import io.netty.util.internal.SystemPropertyUtil;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadFactory;

/**
 * @author GaoFans
 */
public class SelectableExecutorGroup extends MultiThreadSelectableExecutorGroup {

    private static final int DEFAULT_EVENT_LOOP_THREADS = Math.max(1, SystemPropertyUtil.getInt("io.netty.eventLoopThreads", NettyRuntime.availableProcessors() * 2));

    public SelectableExecutorGroup(int nThreads) {
        this(isPowerOfTwo(nThreads == 0?DEFAULT_EVENT_LOOP_THREADS:nThreads), null);
    }
    public SelectableExecutorGroup(int nThreads, ThreadFactory threadFactory, int maxPendingTasks,
                                   RejectedExecutionHandler rejectedHandler) {
        super(nThreads, threadFactory, maxPendingTasks, rejectedHandler);
    }

    public SelectableExecutorGroup(int nThreads, ThreadFactory threadFactory) {
        this(nThreads, threadFactory, Math.max(16, SystemPropertyUtil.getInt("io.netty.eventexecutor.maxPendingTasks", 2147483647)),
                RejectedExecutionHandlers.reject());
    }

    @Override
    protected EventExecutor newChild(Executor executor, Object... args) throws Exception {
        return new DefaultEventExecutor(this, executor, (Integer) args[0], (RejectedExecutionHandler) args[1]);
    }

    private static int isPowerOfTwo(int val) {
        assert val > 0 : "must > 0";
        assert (val & -val) == val : "must power of 2";
        return val;
    }
}
